package com.yinjing.service;

import com.yinjing.pojo.ResultModel;
import com.yinjing.pojo.Sku;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.*;
import org.springframework.data.solr.core.query.result.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author lizehui
 */
@Service
public class SearchServiceImpl implements SearchService {
    private static final String[] colors = {"red", "yellow", "blue", "yellow", "violet", "brown", "greenyellow", "plum"};

    @Autowired
    private SolrTemplate solrTemplate;

    @Value("${solr.core}")
    private String solrCore;

    //每页显示记录数
    private static final Integer PAGE_NUM = 5;


    @Override
    public ResultModel search(String queryString, String price, Integer page) {
        //1. 创建高亮查询对象
        HighlightQuery solrQuery = new SimpleHighlightQuery();
        //设置高亮的域
        HighlightOptions highlightOptions = new HighlightOptions().addField("name");
        //高亮前缀
        highlightOptions.setSimplePrefix("<span style='color:" + null + "'>");
        //高亮后缀
        highlightOptions.setSimplePostfix("</span>");
        //设置高亮选项
        solrQuery.setHighlightOptions(highlightOptions);
        //获取分词


        //2. 创建查询条件
        if (queryString != null) {
            Criteria criteria = new Criteria("name").is(queryString);
           /*for (int i = 0; i < query.size(); i++) {
               //3. 将查询条件添加到查询对象中
               criteria.or("name").in(query.get(i));
            }*/
            solrQuery.addCriteria(criteria);
        }

        //4. 分页
        //计算从第几条开始查询
        Long startRows = (long) (page - 1) * PAGE_NUM;

        solrQuery.setOffset(startRows);//开始索引（默认0）
        solrQuery.setRows(PAGE_NUM);//每页记录数(默认10)

        //5. 排序
        Sort sort = new Sort(Sort.Direction.DESC, "price");
        solrQuery.addSort(sort);

        //6. 按照价格过滤查询
        if (!StringUtils.isEmpty(price)) {
            String[] priceArray = price.split("-");
            Criteria criteriaPrice1 = new Criteria("price").greaterThanEqual(priceArray[0]);
            Criteria criteriaPrice2 = new Criteria("price").lessThanEqual(priceArray[1]);
            solrQuery.addCriteria(criteriaPrice1);
            solrQuery.addCriteria(criteriaPrice2);
        }
        //System.out.println(solrQuery.toString());
        // solrQuery.setHighlightOptions()
        //7. 查询并返回结果
        HighlightPage<Sku> skuPage = solrTemplate.queryForHighlightPage(solrCore, solrQuery, Sku.class);

        //8. 获取查询到的总条数
        long count = skuPage.getTotalElements();
        if(StringUtils.isEmpty(price)){
            System.out.println("全部价格区间，获取查询到的总条数" + count);
        }else {
            System.out.println(price + " 获取查询到的总条数" + count);
        }

        //9. 获取查询结果集
        List<Sku> content = skuPage.getContent();
        int nameCount = 0;
        //循环高亮入口集合
        for (HighlightEntry<Sku> h : skuPage.getHighlighted()) {
            Sku sku = h.getEntity();//获取原实体类
            if (h.getHighlights().size() > 0 && h.getHighlights().get(0).getSnipplets().size() > 0) {
                String title = h.getHighlights().get(0).getSnipplets().get(0);
                String[] strings = title.split("'color:null'");
                StringBuffer stringBuffer = new StringBuffer(strings[0]);
                for (int i = 1; i < strings.length; i++) {
                    nameCount++;
                    stringBuffer.append("color:" + colors[i-1] + "" + strings[i]);
                }
                //设置高亮的结果
                sku.setTitle(stringBuffer.toString());
            }
        }
        System.out.println(queryString + "出现：" + nameCount);

        //10. 获取总页数
        int totalPages = skuPage.getTotalPages();

        ResultModel resultModel = new ResultModel();
        resultModel.setCurPage(page);
        resultModel.setPageCount((long) totalPages);
        resultModel.setRecordCount(count);
        resultModel.setSkuList(skuPage.getContent());
        return resultModel;
    }


    /**
     * 分组查询, 按照品牌分组
     *
     * @return
     */
    private List<String> searchBrandList(String queryString) {
        List<String> list = new ArrayList();
        Query query = new SimpleQuery();

        //按照关键字查询
        Criteria criteria = new Criteria("name").is(queryString);
        query.addCriteria(criteria);

        //设置分组选项
        GroupOptions groupOptions = new GroupOptions().addGroupByField("brand_name");
        //分组结果从第几条开始查询
        groupOptions.setOffset(0);
        //分组结果返回多少条数据
        groupOptions.setLimit(-1);

        query.setGroupOptions(groupOptions);

        //得到分组页
        GroupPage<Sku> page = solrTemplate.queryForGroupPage(solrCore, query, Sku.class);
        //根据列得到分组结果集
        GroupResult<Sku> groupResult = page.getGroupResult("brand_name");
        //得到分组结果入口页
        Page<GroupEntry<Sku>> groupEntries = groupResult.getGroupEntries();
        //得到分组入口集合
        List<GroupEntry<Sku>> content = groupEntries.getContent();
        for (GroupEntry<Sku> entry : content) {
            list.add(entry.getGroupValue());//将分组结果的名称封装到返回值中
        }
        return list;
    }

    /**
     * IK分词
     *
     * @param target
     * @return
     */
    public static List<String> iKSegmenterToList(String target) {
        try {
            if (StringUtils.isEmpty(target)) {
                return new ArrayList<>();
            }
            List<String> result = new ArrayList<>();
            StringReader sr = new StringReader(target);
            // 关闭智能分词 (对分词的精度影响较大)
            IKSegmenter ik = new IKSegmenter(sr, false);
            Lexeme lex;
            while (true) {

                if (!((lex = ik.next()) != null)) break;

                String lexemeText = lex.getLexemeText();
                result.add("'"+lexemeText+"'");
            }

            //LOGGER.info("company:{}, iKSegmenterToList:{}", target, JSON.toJSON(result));
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }

    public static void main(String[] args) {
        System.out.println(iKSegmenterToList("俄罗斯国防部"));
    }

}
